/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 * 
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 * 
 * Last Modified: 2016-02-16
 ******************************************************************************/
package cn.com.xy.sms.sdk.db.entity;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.DBManager;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.util.StringUtils;

/**
 * @author Jinjia
 *
 *         号码短信识别记录器
 */
public class SmsParseRecorder {
	/**
	 * 电话号码列
	 */
	private static final String COLUMN_PHONE_NUM = "phone_num";
	/**
	 * 短信数量列
	 */
	private static final String COLUMN_SMS_NUM = "sms_num";
	/**
	 * 识别成功次数列
	 */
	private static final String COLUMN_SUCCESS_NUM = "success_num";
	/**
	 * 识别日期时间
	 */
	private static final String COLUMN_DATE_TIME = "date_time";
	/**
	 * 查询标记，1 表示正在查询，0 表示空闲状态
	 */
	private static final String COLUMN_QUERY_FLAG = "query_flag";

	/**
	 * 号码短信识别数据表
	 */
	private static final String TABLE_NAME = "tb_sms_parse_recorder";

	/**
	 * 删除数据表
	 */
	public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
	
	/**
	 * 创建数据表
	 */
	public static final String CREATE_TABLE = "CREATE TABLE  IF NOT EXISTS " + TABLE_NAME + " (" 
	        + COLUMN_PHONE_NUM + " TEXT, "
			+ COLUMN_SMS_NUM + " INTEGER DEFAULT 0, " 
			+ COLUMN_SUCCESS_NUM + " INTEGER DEFAULT 0, "
			+ COLUMN_DATE_TIME + " INTEGER DEFAULT 0, "
			+ COLUMN_QUERY_FLAG + " INTEGER DEFAULT 0"
			+ ")";
	
	/**
	 * 查询该号码当天是否解析过
	 */
    private static final String SQL_QUERY_EXIST_PHONE_NUM = "SELECT 1 FROM " + TABLE_NAME 
            + " WHERE " + COLUMN_PHONE_NUM
            + " = ? AND " + COLUMN_DATE_TIME + " = ?";
	
	/**
	 * 更新解析短信识别次数
	 */
	private static final String SQL_UPDATE_PARSE_SMS_COUNT = "UPDATE " + TABLE_NAME + " SET " 
			+ COLUMN_SMS_NUM + " = " + COLUMN_SMS_NUM + " + 1, "
			+ COLUMN_SUCCESS_NUM + " = " + COLUMN_SUCCESS_NUM + " + ? "
			+ "WHERE " + COLUMN_PHONE_NUM + " = ? AND " + COLUMN_DATE_TIME + " = ?";
	
	/**
	 * 解析短信记录器
	 * 
	 * @param phoneNum 手机号码
	 * @param isSuccess 是否解析成功
	 */
	public static void addRecord(String phoneNum, boolean isSuccess) {
		if (StringUtils.isNull(phoneNum)) {
			LogManager.w(Constant.TAG, "phoneNum is null！");
			return;
		}
		
		SQLiteDatabase db = null;

		try {
			db = DBManager.getSQLiteDatabase();
			if (db == null) {
				LogManager.w(Constant.TAG, "getSQLiteDatabase 为空！");
				return;
			}
			
			//	查询该当天的号码是否在数据表中，若不存在，需要先将号码插入到表中
			long time = getTimesMorning();
			Cursor existPhoneNumCursor = db.rawQuery(SQL_QUERY_EXIST_PHONE_NUM, new String[] { phoneNum, String.valueOf(time) });
			boolean existPhoneNum = false;
			if (existPhoneNumCursor != null) {
				existPhoneNum = (existPhoneNumCursor.getCount() != 0);
				existPhoneNumCursor.close();
			}
			
			if (!existPhoneNum) {    //  不存在，将数据项插入到数据库中
                ContentValues values = new ContentValues();
                values.put(COLUMN_PHONE_NUM, phoneNum);
                values.put(COLUMN_SMS_NUM, 1);
                values.put(COLUMN_SUCCESS_NUM, isSuccess ? 1 : 0);
                values.put(COLUMN_DATE_TIME, time);
                
                db.insert(TABLE_NAME, null, values);
            } else {    //  存在，更新记录
                db.execSQL(SQL_UPDATE_PARSE_SMS_COUNT, new String[] { isSuccess ? "1" : "0", phoneNum, String.valueOf(time) });
            }
		} catch (Throwable e) {
		    /*SDK-550 hewengao 20160719 start*/
			LogManager.w(Constant.TAG, "addRecord error: ", e);
			/*SDK-550 hewengao 20160719 end*/
		} finally {
			if (db != null) {
				DBManager.close(db);
			}
		}
	}
	
    /**
     * 获得当天0点时间
     * 
     * @return 当天0点时间
     */
    private static long getTimesMorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTimeInMillis();
    }
	
    /**
     * 一天的毫秒数
     */
    private static final long DAY = 1000 * 3600 * 24;
	
	/**
	 * 根据号码查询解析识别数据
     * 
     * @param phoneNumList 号码列表
     * @return Map<phoneNum, Map<ac: 短信数量, rc: 成功识别数量，dt: 据上报日期的天数>>
	 */
	public static Map<String, Map<String, StringBuilder>> getParseSmsRecordByPhoneNum(List<String> phoneNumList) {
	    // Map<phoneNum, Map<ac: 短信数量, rc: 成功识别数量，dt: 据上报日期的天数>>
	    Map<String, Map<String, StringBuilder>> result = new HashMap<String, Map<String, StringBuilder>>();
	    if (phoneNumList == null || phoneNumList.isEmpty()) {
	        return result;
	    }

	    SQLiteDatabase db = DBManager.getSQLiteDatabase();
        if (db == null) {
            LogManager.w(Constant.TAG, "getParseSmsRecordByPhoneNum: getSQLiteDatabase 为空！");
            return result;
        }
	    
	    // 构造查询条件：号码一致，并且不是当天的数据
	    String[] columns = new String[] { COLUMN_SMS_NUM, COLUMN_SUCCESS_NUM, COLUMN_DATE_TIME, COLUMN_PHONE_NUM };
	    String placeholders = makePlaceholders(phoneNumList.size());
        String selection = COLUMN_DATE_TIME + " < " + getTimesMorning()  + " AND "+ COLUMN_PHONE_NUM + " IN(" + placeholders + ")";
        String[] selectionArgs = phoneNumList.toArray(new String[phoneNumList.size()]);

        Cursor cursor = db.query(TABLE_NAME, columns, selection, selectionArgs, null, null, null);
        if (cursor == null) {
            return result;
        }
        
        while (cursor.moveToNext()) {
            String phoneNum = cursor.getString(cursor.getColumnIndex(COLUMN_PHONE_NUM));
            
            StringBuilder ac; //  短信总数
            StringBuilder rc; //  识别成功数
            StringBuilder dt; //  据上报日期的天数
            
            //  如果该号码已经在 result map 中了，说明该号码对应多条数据，使用英文逗号分隔  
            if (result.containsKey(phoneNum)) {
                Map<String, StringBuilder> map = result.get(phoneNum);
                ac = map.get("ac");
                rc = map.get("rc");
                dt = map.get("dt");
                
                ac.append(',');
                rc.append(',');
                dt.append(',');
            } else {
                Map<String, StringBuilder> map = new HashMap<String, StringBuilder>();
                ac = new StringBuilder();
                rc = new StringBuilder();
                dt = new StringBuilder();
                
                map.put("ac", ac);
                map.put("rc", rc);
                map.put("dt", dt);
                result.put(phoneNum, map);
            }
            
            int smsNum = cursor.getInt(cursor.getColumnIndex(COLUMN_SMS_NUM));
            int successNum = cursor.getInt(cursor.getColumnIndex(COLUMN_SUCCESS_NUM));
            long dateTime = cursor.getLong(cursor.getColumnIndex(COLUMN_DATE_TIME));
            int days = (int) ((System.currentTimeMillis() - dateTime) / DAY);   //  当前时间 减去 短信解析时间的时间差，得到天数
            
            ac.append(smsNum);
            rc.append(successNum);
            dt.append(days);
        }
        
        cursor.close();
        
        //  根据号码和时间标记为查询状态
        ContentValues values = new ContentValues();
        values.put(COLUMN_QUERY_FLAG, 1);
        String whereClause = selection;
        try {
            db.beginTransaction();
            
            for (String phoneNum : phoneNumList) {
                db.update(TABLE_NAME, values, whereClause, new String[] { phoneNum });
            }
            
            db.setTransactionSuccessful();
        } catch (Throwable e) {
            /*SDK-550 hewengao 20160719 start*/
            LogManager.w(Constant.TAG, "getParseSmsRecordByPhoneNum error:", e);
            /*SDK-550 hewengao 20160719 end*/
        } finally {
            if (db.inTransaction()) {
                db.endTransaction();
            }
        }
        
        DBManager.close(db);
	    return result;
	}
	
	/**
     * 创建占位符
     * 
     * @param size 数据
     * @return 占位符
     */
    public static String makePlaceholders(int size) {
        if (size <= 0) {
            return null;
        }

        StringBuilder sb = new StringBuilder(size * 2 - 1);
        sb.append("?");
        for (int i = 1; i < size; i++) {
            sb.append(",?");
        }

        return sb.toString();
    }
	
	/**
	 * 如果更新成功，则删除该行记录；如果更新失败，则需要更新查询标记转为0
	 * 
	 * @param isSuccess 是否处理成功
	 */
	public static void updateParseSmsRecord(boolean isSuccess) {
	    String whereClause = COLUMN_QUERY_FLAG + "=1";
	    
	    if (isSuccess) {
	        try {
	            DBManager.delete(TABLE_NAME, whereClause, null);
	        } catch (Exception e) {
	            /*SDK-550 hewengao 20160719 start*/
	            LogManager.w(Constant.TAG, "updateParseSmsRecord error", e);
	            /*SDK-550 hewengao 20160719 end*/
	        }
	    } else {
	        ContentValues values = new ContentValues();
	        values.put(COLUMN_QUERY_FLAG, 0);
	        
	        try {
                DBManager.update(TABLE_NAME, values, whereClause, null);
            } catch (Exception e) {
                /*SDK-550 hewengao 20160719 start*/
                LogManager.w(Constant.TAG, "updateParseSmsRecord error", e);
                /*SDK-550 hewengao 20160719 end*/
            }
	    }
	}
}
